﻿using LoveEat.MODEL.WeChat;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace LoveEat.WeChat
{
    public class PayForWeiXinHelp
    {

        /// <summary>
        /// 调用微信支付接口前处理数据，包括sign验证等
        /// </summary>
        public string DoDataForPayWeiXin(PayWeiXin payForWeiXin)
        {
            payForWeiXin.act_id = "act_id";
            //调用接口的机器 Ip 地址

            #region 处理nonce_str随机字符串，不长于 32 位（本程序生成长度为16位的）

            payForWeiXin.nonce_str = GenNoncestr(16);
            #endregion
            //原始传入参数
            string[] signTemp = { "mch_billno=" + payForWeiXin.mch_billno, "mch_id=" + payForWeiXin.mch_id, "wxappid=" + payForWeiXin.AppId, "send_name=" + payForWeiXin.send_name, "re_openid=" + payForWeiXin.re_openid, "total_amount=" + payForWeiXin.total_amount, "total_num=" + payForWeiXin.total_num, "wishing=" + payForWeiXin.wishing, "client_ip=" + payForWeiXin.client_ip, "act_name=" + payForWeiXin.act_name, "act_id=" + payForWeiXin.act_id, "remark=" + payForWeiXin.remark, "nonce_str=" + payForWeiXin.nonce_str };

            List<string> signList = signTemp.ToList();
            #region 处理支付签名
            //对signList按照ASCII码从小到大的顺序排序
            signList.Sort();

            string signOld = string.Empty;
            string payForWeiXinOld = string.Empty;
            int i = 0;
            foreach (string temp in signList)
            {
                signOld += temp + "&";
                i++;
            }
            signOld = signOld.Substring(0, signOld.Length - 1);
            //拼接Key
            signOld += "&key=" + payForWeiXin.PayKey;
            //处理支付签名
            payForWeiXin.sign = Encrypt(signOld).ToUpper();
            #endregion
            string postData = @"<xml> 
                                 <mch_billno>{0}</mch_billno> 
                                 <mch_id>{1}</mch_id> 
                                 <wxappid>{2}</wxappid> 
                                 <send_name>{3}</send_name> 
                                 <re_openid>{4}</re_openid> 
                                 <total_amount>{5}</total_amount>
                                  <total_num>{6}</total_num> 
                                 <wishing>{7}</wishing> 
                                 <client_ip>{8}</client_ip> 
                                 <act_name>{9}</act_name> 
                                 <act_id>{10}</act_id> 
                                 <remark>{11}</remark>
                                 <nonce_str>{12}</nonce_str>
                                    <sign>{13}</sign></xml>";
            postData = string.Format(postData,
                                            payForWeiXin.mch_billno,//商户订单号
                                            payForWeiXin.mch_id,//商户号
                                            payForWeiXin.AppId, payForWeiXin.send_name,
                                            payForWeiXin.re_openid,
                                            payForWeiXin.total_amount, payForWeiXin.total_num,
                                            payForWeiXin.wishing,
                                            payForWeiXin.client_ip,
                                            payForWeiXin.act_name,
                                            payForWeiXin.act_id,
                                            payForWeiXin.remark,
                                            payForWeiXin.nonce_str,
                                            payForWeiXin.sign
                                );

            return postData;
        }

        /// <summary>
        /// 调用微信支付接口
        /// </summary>
        /// <param name="payForWeiXin"></param>
        /// <returns></returns>
        public string PayForWeiXin(string postData)
        {
            string result = string.Empty;
            try
            {
                result = PostPage("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", postData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }
        public static string PostPage(string url, string xmldata)
        {
            //证书地址,并且双击apiclient_cert.p12安装证书
            string cert = ConfigurationManager.AppSettings["certPath"].ToString(); ;
            string password = ConfigurationManager.AppSettings["password"].ToString();
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);

            //****************注意*********************
            //这里添加 证书要注意，在本地调试的时候
            //本地调试用这个
            // X509Certificate cer = new X509Certificate(cert, password);
            //上传服务器上用这个
            X509Certificate2 cer = new X509Certificate2(cert, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
            HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
            webrequest.ClientCertificates.Add(cer);
            webrequest.Method = "post";
            webrequest.UseDefaultCredentials = true;
            //添加xml数据
            StreamWriter swMessages = new StreamWriter(webrequest.GetRequestStream());
            //写入的流以XMl格式写入
            swMessages.Write(xmldata);
            //关闭写入流
            swMessages.Close();

            HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();
            Stream stream = webreponse.GetResponseStream();
            string resp = string.Empty;
            using (StreamReader reader = new StreamReader(stream))
            {
                resp = reader.ReadToEnd();
            }
            return resp;


        }
        /*CheckValidationResult的定义*/
        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            if (errors == SslPolicyErrors.None)
                return true;
            return false;
        }
        //生成随机字符
        public static string GenNoncestr(int length)
        {
            Random r = new Random();
            string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            string noncestr = "";
            for (int i = 0; i < length; i++)
            {
                noncestr += str[r.Next(str.Length)];
            }
            return noncestr;
        }

        public string RandomStr(string str, int Length)
        {
            string result = string.Empty;
            Random rd = new Random();
            for (int i = 0; i < Length; i++)
            {
                result += str[rd.Next(str.Length)];
            }
            return result;
        }

        /// <summary>
        /// Md5加密
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static String Encrypt(String s)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s);
            bytes = md5.ComputeHash(bytes);
            md5.Clear();
            string ret = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
            }
            return ret.PadLeft(32, '0');
        }


        #region 查询红包接口
        public string GetDataForPayWeiXin(PayWeiXin payForWeiXin)
        {
            #region 处理nonce_str随机字符串，不长于 32 位（本程序生成长度为16位的）

            payForWeiXin.nonce_str = GenNoncestr(16);
            #endregion
            //原始传入参数
            string[] signTemp = { "mch_billno=" + payForWeiXin.mch_billno, "mch_id=" + payForWeiXin.MchId, "appid=" + payForWeiXin.AppId, "bill_type=MCHT", "nonce_str=" + payForWeiXin.nonce_str };

            List<string> signList = signTemp.ToList();
            #region 处理支付签名
            //对signList按照ASCII码从小到大的顺序排序
            signList.Sort();

            string signOld = string.Empty;
            string payForWeiXinOld = string.Empty;
            int i = 0;
            foreach (string temp in signList)
            {
                signOld += temp + "&";
                i++;
            }
            signOld = signOld.Substring(0, signOld.Length - 1);
            //拼接Key
            signOld += "&key=" + payForWeiXin.PayKey;
            //处理支付签名
            payForWeiXin.sign = Encrypt(signOld).ToUpper();
            #endregion
            string postData = @"<xml>
                                 <sign>{5}</sign> 
                                 <mch_billno>{0}</mch_billno> 
                                 <mch_id>{1}</mch_id> 
                                 <appid>{2}</appid> 
                                 <bill_type>{3}</bill_type> 
                                 <nonce_str>{4}</nonce_str>
                                 </xml>";
            postData = string.Format(postData,
                                            payForWeiXin.mch_billno,//商户订单号
                                            payForWeiXin.MchId,//商户号
                                            payForWeiXin.AppId,
                                            "MCHT",
                                            payForWeiXin.nonce_str,
                                            payForWeiXin.sign
                                );

            return postData;
        }


        public string GetForWeiXin(string postData)
        {
            string result = string.Empty;
            try
            {
                result = PostPage("https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo", postData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }
        #endregion
    }
}
